package cn.edu.fzu.homemaking.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;

import com.google.common.collect.ImmutableMap;

/**
 * @author zhangyan
 * @date 2019年8月19日
 */
abstract class AbstractHttpClient implements HttpClient {

    protected static final Map<String, String> EMPTY_MAP   = ImmutableMap.of();
    protected static final byte[]              EMPTY_BYTES = new byte[0];

    protected Charset                          charset;

    @Override
    public final @Nullable String get(String url) throws IOException {
        byte[] result = execute(true, url, EMPTY_MAP, EMPTY_MAP, null);
        return result == null ? null : new String(result, charset);
    }


    @Override
    public final @Nullable byte[] post(String url, String content) throws IOException {
        return execute(false, url, EMPTY_MAP, EMPTY_MAP, content.getBytes(charset));
    }


    @Override
    public final @Nullable byte[] post(String url, Map<String, String> headers, String content) throws IOException {
        return execute(false, url, headers, EMPTY_MAP, content.getBytes(charset));
    }


    @Override
    public final @Nullable String post(String url, Map<String, String> parameters) throws IOException {
        byte[] result = execute(false, url, EMPTY_MAP, parameters, null);
        return result == null ? null : new String(result, charset);
    }


    protected abstract @Nullable byte[] execute(boolean get, String url, Map<String, String> headers,
                                                Map<String, String> parameters, @Nullable byte[] content)
            throws IOException;


    /** join parameters to url, return full url **/
    protected final String join(Map<String, String> parameters, String url) throws UnsupportedEncodingException {

        if (MapUtils.isEmpty(parameters)) {
            return url;
        }

        // url 里是否已包含了问号
        boolean containsInterrogation = (url.indexOf('?') != -1);

        StringBuilder fullUrl = new StringBuilder(url);
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
            if (containsInterrogation) {
                fullUrl.append('&');
            } else {
                fullUrl.append('?');
                containsInterrogation = true;
            }

            fullUrl.append(entry.getKey()).append('=');
            if (StringUtils.isNotEmpty(entry.getValue())) {
                fullUrl.append(URLEncoder.encode(entry.getValue(), charset.name()));
            }
        }
        return fullUrl.toString();
    }

}
